


<!DOCTYPE html>
<html id="htmlId">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> 
  <title>Coverage Report > RedisConfig</title>
  <style type="text/css">
    @import "../../css/coverage.css";
    @import "../../css/idea.min.css";
  </style>
  <script type="text/javascript" src="../../js/highlight.min.js"></script>
  <script type="text/javascript" src="../../js/highlightjs-line-numbers.min.js"></script>
</head>

<body>
<div class="content">
<div class="breadCrumbs">
Current scope:     <a href="../../index.html">all classes</a>
    <span class="separator">|</span>
    <a href="../index.html">com.ie.common.config</a>
</div>

<h1>Coverage Summary for Class: RedisConfig (com.ie.common.config)</h1>

<table class="coverageStats">

<tr>
  <th class="name">Class</th>
<th class="coverageStat 
">
  Method, %
</th>
<th class="coverageStat 
">
  Branch, %
</th>
<th class="coverageStat 
">
  Line, %
</th>
</tr>
<tr>
  <td class="name">RedisConfig</td>
<td class="coverageStat">
  <span class="percent">
    100%
  </span>
  <span class="absValue">
    (5/5)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    100%
  </span>
  <span class="absValue">
    (35/35)
  </span>
</td>
</tr>
  <tr>
    <td class="name">RedisConfig$$SpringCGLIB$$0</td>
  </tr>
  <tr>
    <td class="name">RedisConfig$$SpringCGLIB$$FastClass$$0</td>
  </tr>
  <tr>
    <td class="name">RedisConfig$$SpringCGLIB$$FastClass$$1</td>
  </tr>
  <tr>
    <td class="name">RedisConfig$1</td>
<td class="coverageStat">
  <span class="percent">
    50%
  </span>
  <span class="absValue">
    (1/2)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    0%
  </span>
  <span class="absValue">
    (0/2)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    14.3%
  </span>
  <span class="absValue">
    (1/7)
  </span>
</td>
  </tr>
<tr>
  <td class="name"><strong>Total</strong></td>
<td class="coverageStat">
  <span class="percent">
    85.7%
  </span>
  <span class="absValue">
    (6/7)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    0%
  </span>
  <span class="absValue">
    (0/2)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    85.7%
  </span>
  <span class="absValue">
    (36/42)
  </span>
</td>
</tr>
</table>

<br/>
<br/>


<pre>
<code class="sourceCode" id="sourceCode">&nbsp;package com.ie.common.config;
&nbsp;
&nbsp;import jakarta.annotation.PostConstruct;
&nbsp;import org.springframework.cache.CacheManager;
&nbsp;import org.springframework.cache.annotation.EnableCaching;
&nbsp;import org.springframework.cache.interceptor.KeyGenerator;
&nbsp;import org.springframework.context.annotation.Bean;
&nbsp;import org.springframework.context.annotation.Configuration;
&nbsp;import org.springframework.data.redis.cache.RedisCacheConfiguration;
&nbsp;import org.springframework.data.redis.cache.RedisCacheManager;
&nbsp;import org.springframework.data.redis.connection.RedisConnectionFactory;
&nbsp;import org.springframework.data.redis.core.RedisTemplate;
&nbsp;import org.springframework.data.redis.core.StringRedisTemplate;
&nbsp;import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
&nbsp;import org.springframework.data.redis.serializer.RedisSerializationContext;
&nbsp;import org.springframework.data.redis.serializer.StringRedisSerializer;
&nbsp;
&nbsp;import java.lang.reflect.Method;
&nbsp;import java.time.Duration;
&nbsp;import java.util.HashMap;
&nbsp;import java.util.HashSet;
&nbsp;import java.util.Map;
&nbsp;import java.util.Set;
&nbsp;
&nbsp;/**
&nbsp; * @classname: RedisConfig
&nbsp; * @Author: royxu
&nbsp; * @Description: Redis自定义配置类，Spring Boot会优先使用自定义RedisTemplate
&nbsp; * https://tongyi.aliyun.com/qianwen/?chatId=9cab896dc08a48fe9310519eb94e2d4d&amp;sessionId=be618c3a99a046f989fcfcd95eb9f565
&nbsp; * @Date: 2025/4/16  13:57
&nbsp; * @Param:
&nbsp; * @version: 1.0
&nbsp; **/
&nbsp;@Configuration
&nbsp;@EnableCaching
<b class="fc">&nbsp;public class RedisConfig {</b>
&nbsp;    /*
&nbsp;     这段Java代码定义了一个Spring Bean，名为`keyGenerator`，它返回一个`KeyGenerator`对象。`KeyGenerator`是一个接口，
&nbsp;     通常用于生成键值，例如在缓存中生成唯一的键。这个自定义的`KeyGenerator`实现通过组合目标类名、方法名和参数来生成键。
&nbsp;     1. 定义Bean：使用`@Bean`注解将`keyGenerator`方法标记为一个Spring Bean，这样Spring容器在启动时会自动调用这个方法并注册
&nbsp;     返回的`KeyGenerator`对象。
&nbsp;     2. 匿名内部类：`keyGenerator`方法返回一个匿名内部类，这个内部类实现了`KeyGenerator`接口。
&nbsp;     3. 生成键的逻辑：
&nbsp;     - 使用`StringBuilder`来构建键字符串。
&nbsp;     - `target.getClass().getName()`获取目标类的全限定名。
&nbsp;     - `method.getName()`获取方法的名称。
&nbsp;     - 遍历方法的参数，将每个参数的`toString()`方法结果追加到`StringBuilder`中。
&nbsp;     4. 返回键：将构建好的键字符串返回。
&nbsp;     用途
&nbsp;     这个自定义的`KeyGenerator`可以用于生成缓存键，确保每个缓存条目都有一个唯一的键，即使调用的是同一个方法，只要参数不同，
&nbsp;     生成的键也会不同。
&nbsp;     1. 性能：每次调用`generate`方法时都会创建一个新的`StringBuilder`对象，这可能会影响性能。如果性能是一个关键考虑因素，
&nbsp;     可以考虑使用更高效的数据结构或缓存机制。
&nbsp;     2. 线程安全：`StringBuilder`不是线程安全的，如果`KeyGenerator`可能会在多线程环境中使用，需要确保线程安全。
&nbsp;     3. 键的长度：生成的键长度可能会随着参数数量的增加而增加，这可能会影响缓存系统的性能。如果键的长度过长，可能需要考虑优化键的生成逻辑。
&nbsp;     4. 参数类型：如果参数是复杂对象，直接调用`toString()`方法可能不会得到预期的结果。可能需要自定义参数的字符串表示形式。
&nbsp;     */
&nbsp;
&nbsp;    /**
&nbsp;     * @Description: 自定义缓存key生成器
&nbsp;     * @Author: royxu
&nbsp;     * @Date: 2025/4/21  8:48
&nbsp;     * @Param: []
&nbsp;     * @version: 1.0
&nbsp;     * @Return: org.springframework.cache.interceptor.KeyGenerator
&nbsp;     **/
&nbsp;    @Bean
&nbsp;    public KeyGenerator keyGenerator() {
<b class="fc">&nbsp;        return new KeyGenerator() {</b>
&nbsp;            /**
&nbsp;             * @Description: 匿名内部类，用于生成缓存键
&nbsp;             * @Author: royxu
&nbsp;             * @Date: 2025/4/21  8:48
&nbsp;             * @Param: [target, method, params]：条用方法的目标对象实例、被调用的方法、方法可变参数列表
&nbsp;             * @version: 1.0
&nbsp;             * @Return: java.lang.Object
&nbsp;             **/
&nbsp;            @Override
&nbsp;            public Object generate(Object target, Method method, Object... params) {
<b class="nc">&nbsp;                StringBuilder sb = new StringBuilder();</b>
&nbsp;                // 添加目标类的全限定名
<b class="nc">&nbsp;                sb.append(target.getClass().getName());</b>
&nbsp;                // 添加方法名，前面用 &quot;#&quot; 分隔
<b class="nc">&nbsp;                sb.append(&quot;#&quot; + method.getName());</b>
<b class="nc">&nbsp;                for (Object obj : params) {</b>
&nbsp;                    // 将所有参数拼接起来
<b class="nc">&nbsp;                    sb.append(obj.toString());</b>
&nbsp;                }
<b class="nc">&nbsp;                return sb.toString();</b>
&nbsp;            }
&nbsp;        };
&nbsp;    }
&nbsp;
&nbsp;    /**
&nbsp;     * @Description: 在Spring应用中使用Redis作为缓存，Redis 缓存的配置，包括缓存名称、过期时间、序列化方式以提升性能和响应速度。
&nbsp;     * 通过配置不同的缓存名称和过期时间，可以灵活地管理不同类型的数据缓存.
&nbsp;     * @Author: royxu
&nbsp;     * @Date: 2025/4/21  9:07
&nbsp;     * @Param: [redisConnectionFactory]
&nbsp;     * @version: 1.0
&nbsp;     * @Return: org.springframework.cache.CacheManager
&nbsp;     **/
&nbsp;    @Bean
&nbsp;    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
&nbsp;        // 用于序列化 Redis 的键（Key），确保键以字符串形式存储（如 &quot;user:1&quot;）。
<b class="fc">&nbsp;        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();</b>
&nbsp;        // 用于序列化 Redis 的值（Value），将 Java 对象转换为 JSON 格式存储（如 {&quot;id&quot;:1, &quot;name&quot;:&quot;Alice&quot;}）。
&nbsp;        // 这里使用 Object.class，表示支持任意类型的对象序列化。
<b class="fc">&nbsp;        Jackson2JsonRedisSerializer&lt;Object&gt; jacksonSerializer = new Jackson2JsonRedisSerializer&lt;&gt;(Object.class);</b>
&nbsp;
<b class="fc">&nbsp;        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();</b>
&nbsp;        // 默认缓存过期时间：60 分钟
<b class="fc">&nbsp;        config = config.entryTtl(Duration.ofMinutes(60))</b>
&nbsp;                // 键的序列化方式
<b class="fc">&nbsp;                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer))</b>
&nbsp;                // 值的序列化方式
<b class="fc">&nbsp;                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jacksonSerializer))</b>
&nbsp;                // 禁止缓存 null 值
<b class="fc">&nbsp;                .disableCachingNullValues();</b>
&nbsp;        // 声明需要管理的缓存名称集合（timeGroup 和 user）。
<b class="fc">&nbsp;        Set&lt;String&gt; cacheNames = new HashSet&lt;&gt;();</b>
&nbsp;        // 缓存名称 1
<b class="fc">&nbsp;        cacheNames.add(&quot;timeGroup&quot;);</b>
&nbsp;        // 缓存名称 2
<b class="fc">&nbsp;        cacheNames.add(&quot;user&quot;);</b>
<b class="fc">&nbsp;        Map&lt;String, RedisCacheConfiguration&gt; configMap = new HashMap&lt;&gt;();</b>
&nbsp;        // &quot;timeGroup&quot; 使用默认配置（TTL=60 分钟）
<b class="fc">&nbsp;        configMap.put(&quot;timeGroup&quot;, config);</b>
&nbsp;        // &quot;user&quot; 自定义 TTL=120 秒
<b class="fc">&nbsp;        configMap.put(&quot;user&quot;, config.entryTtl(Duration.ofSeconds(120)));</b>
&nbsp;        // 构建 RedisCacheManager
<b class="fc">&nbsp;        RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)</b>
&nbsp;                // 设置默认缓存配置（这里似乎覆盖了之前的 config，可能是一个冗余代码）
<b class="fc">&nbsp;                .cacheDefaults(RedisCacheConfiguration.defaultCacheConfig(Thread.currentThread().getContextClassLoader()))</b>
&nbsp;                // 初始化缓存名称集合
<b class="fc">&nbsp;                .initialCacheNames(cacheNames).withInitialCacheConfigurations(configMap).build();</b>
<b class="fc">&nbsp;        System.out.println(&quot;This is Redis:cacheManager!&quot;);</b>
<b class="fc">&nbsp;        return cacheManager;</b>
&nbsp;    }
&nbsp;
&nbsp;    /*
&nbsp;     * 这段Java代码定义了一个Spring Bean，用于配置一个`RedisTemplate`实例，该实例用于与Redis数据库进行交互。`RedisTemplate`是
&nbsp;     * Spring Data Redis 提供的一个高级抽象，用于简化与Redis的交互操作
&nbsp;     * 1. 定义Bean：使用`@Bean`注解，表明该方法返回的对象是一个Spring Bean，Spring容器会管理这个Bean的生命周期。
&nbsp;     * 2. 参数注入：方法接收一个`RedisConnectionFactory`类型的参数，这是Spring Data Redis用于创建与Redis服务器连接的工厂。
&nbsp;     * 3. 序列化器配置：
&nbsp;     * - `StringRedisSerializer`：用于序列化和反序列化Redis的键（key）。
&nbsp;     * - `Jackson2JsonRedisSerializer`：用于序列化和反序列化Redis的值（value），这里使用Jackson库将对象序列化为JSON格式。
&nbsp;     * 4. 创建RedisTemplate实例：
&nbsp;     * - 创建一个`RedisTemplate&lt;String, Object&gt;`实例，指定键和值的类型。
&nbsp;     * - 设置连接工厂`connectionFactory`。
&nbsp;     * - 设置键和值的序列化器。
&nbsp;     * - 设置哈希键和哈希值的序列化器。
&nbsp;     * - 调用`afterPropertiesSet()`方法，初始化模板。
&nbsp;     * 5. 返回模板：返回配置好的`RedisTemplate`实例。
&nbsp;     * ### 用途
&nbsp;     * 这段代码的用途是在Spring应用中配置一个`RedisTemplate`，用于与Redis数据库进行交互。通过配置`RedisTemplate`，
&nbsp;     * 可以方便地进行各种Redis操作，如存储、获取、删除键值对等。
&nbsp;     * ### 注意事项
&nbsp;     * 1. 序列化器选择：选择合适的序列化器对于性能和兼容性非常重要。在这个例子中，键使用`StringRedisSerializer`，值使用
&nbsp;     * `Jackson2JsonRedisSerializer`，适用于大多数场景。
&nbsp;     * 2. Jackson依赖：使用`Jackson2JsonRedisSerializer`需要项目中包含Jackson库的依赖。
&nbsp;     * 3. 配置文件：确保在Spring配置文件中启用了Redis支持，并且正确配置了Redis连接信息。
&nbsp;     * 4. 线程安全：`RedisTemplate`是线程安全的，可以在多个线程中共享使用。
&nbsp;     * 5. 异常处理：在实际应用中，需要对Redis操作可能抛出的异常进行适当的处理，例如网络异常、连接超时等。
&nbsp;     * 通过这段代码，开发者可以轻松地在Spring应用中集成Redis，并利用`RedisTemplate`提供的丰富功能与Redis进行交互。
&nbsp;     */
&nbsp;
&nbsp;    /**
&nbsp;     * @Description: redisTemplate：配置RedisTemplate，用于与Redis进行交互。配置了键和值的序列化方式，以及连接工厂。
&nbsp;     * @Author: royxu
&nbsp;     * @Date: 2025/4/21  9:38
&nbsp;     * @Param: [connectionFactory]
&nbsp;     * @version: 1.0
&nbsp;     * @Return: org.springframework.data.redis.core.RedisTemplate&lt;java.lang.String, java.lang.Object&gt;
&nbsp;     **/
&nbsp;    @Bean
&nbsp;    public RedisTemplate&lt;String, Object&gt; redisTemplate(RedisConnectionFactory connectionFactory) {
&nbsp;        // 用于序列化 Redis 的键（Key），确保键以字符串形式存储（如 &quot;user:1&quot;）
<b class="fc">&nbsp;        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();</b>
&nbsp;        // 用于序列化 Redis 的值（Value），将 Java 对象转换为 JSON 格式存储（如 {&quot;id&quot;:1, &quot;name&quot;:&quot;Alice&quot;}）
<b class="fc">&nbsp;        Jackson2JsonRedisSerializer&lt;Object&gt; jacksonSerializer = new Jackson2JsonRedisSerializer&lt;&gt;(Object.class);</b>
&nbsp;        // Spring Data Redis 的核心类，封装了 Redis 操作（如 set, get, opsForHash 等）
<b class="fc">&nbsp;        RedisTemplate&lt;String, Object&gt; template = new RedisTemplate&lt;&gt;();</b>
&nbsp;        // 注入 Redis 连接工厂（由 Spring Boot 自动配置）
<b class="fc">&nbsp;        template.setConnectionFactory(connectionFactory);</b>
&nbsp;        // 普通键的序列化
<b class="fc">&nbsp;        template.setKeySerializer(stringRedisSerializer);</b>
&nbsp;        // 普通值的序列化
<b class="fc">&nbsp;        template.setValueSerializer(jacksonSerializer);</b>
&nbsp;        // 哈希键的序列化
<b class="fc">&nbsp;        template.setHashKeySerializer(stringRedisSerializer);</b>
&nbsp;        // 哈希值的序列化
<b class="fc">&nbsp;        template.setHashValueSerializer(jacksonSerializer);</b>
&nbsp;        // 调用 afterPropertiesSet() 确保所有属性（如序列化器、连接工厂）已正确设置,类似于 @PostConstruct。
<b class="fc">&nbsp;        template.afterPropertiesSet();</b>
<b class="fc">&nbsp;        System.out.println(&quot;This is Redis:redisTemplate!&quot;);</b>
<b class="fc">&nbsp;        return template;</b>
&nbsp;    }
&nbsp;
&nbsp;    /*
&nbsp;     * 这段Java代码定义了一个Spring Bean，用于创建并配置一个StringRedisTemplate实例。StringRedisTemplate是Spring Data Redis
&nbsp;     * 提供的一个模板类，用于简化与Redis数据库的交互，
&nbsp;     * 特别是针对键值对存储（即字符串类型）的操作。
&nbsp;     * 实现原理
&nbsp;     *
&nbsp;     * @Bean注解：这个注解表明该方法将返回一个对象，该对象要注册为Spring应用上下文中的Bean。Spring容器会管理这个Bean的生命周期。 方法参数：RedisConnectionFactory是一个接口，用于创建和管理与Redis服务器的连接。Spring Data Redis提供了多个实现，
&nbsp;     * 如JedisConnectionFactory或LettuceConnectionFactory。
&nbsp;     * 创建StringRedisTemplate实例：通过调用new StringRedisTemplate()创建一个新的StringRedisTemplate实例。
&nbsp;     * 设置连接工厂：通过调用template.setConnectionFactory(redisConnectionFactory)将传入的RedisConnectionFactory实例设置
&nbsp;     * 到StringRedisTemplate中，
&nbsp;     * 这样StringRedisTemplate就可以使用这个连接工厂来创建和管理与Redis服务器的连接。
&nbsp;     * 返回模板实例：最后，方法返回配置好的StringRedisTemplate实例，Spring容器会将其注册为Bean。
&nbsp;     * 用途
&nbsp;     * StringRedisTemplate主要用于在Spring应用中与Redis进行字符串类型数据的操作，包括但不限于以下功能：
&nbsp;     * 存储和获取字符串数据
&nbsp;     * 执行Redis的字符串操作命令，如SET、GET、INCR等
&nbsp;     * 支持Redis的发布/订阅功能
&nbsp;     * 注意事项
&nbsp;     * 依赖注入：确保在Spring配置文件或配置类中正确配置了RedisConnectionFactory，并且这个Bean可以被Spring容器找到。
&nbsp;     * 连接池配置：如果使用JedisConnectionFactory，可以通过配置JedisPoolConfig来优化Redis连接池的行为。
&nbsp;     * 序列化方式：StringRedisTemplate默认使用StringRedisSerializer来序列化和反序列化数据。如果需要处理复杂对象，可能需要自定义序列化器。
&nbsp;     * 事务支持：StringRedisTemplate支持Redis事务，但需要注意的是，Redis事务在Spring Data Redis中是通过Lua脚本实现的，因此事务的隔离
&nbsp;     * 级别和传统数据库事务有所不同。
&nbsp;     * 通过这段代码，开发者可以方便地在Spring应用中集成Redis，并使用StringRedisTemplate进行高效的字符串类型数据操作。
&nbsp;     */
&nbsp;    /**
&nbsp;     * @Description: stringRedisTemplate：配置StringRedisTemplate，用于与Redis进行字符串类型数据的操作。配置了连接工厂。
&nbsp;     * @Author: royxu
&nbsp;     * @Date: 2025/4/21  10:04
&nbsp;     * @Param: [redisConnectionFactory]
&nbsp;     * @version: 1.0
&nbsp;     * @Return: org.springframework.data.redis.core.StringRedisTemplate
&nbsp;     **/
&nbsp;    @Bean
&nbsp;    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
<b class="fc">&nbsp;        StringRedisTemplate template = new StringRedisTemplate();</b>
<b class="fc">&nbsp;        template.setConnectionFactory(redisConnectionFactory);</b>
<b class="fc">&nbsp;        System.out.println(&quot;This is Redis:stringRedisTemplate初始化成功&quot;);</b>
<b class="fc">&nbsp;        return template;</b>
&nbsp;    }
&nbsp;
&nbsp;}
</code>
</pre>
</div>

<script type="text/javascript">
(function() {
    var msie = false, msie9 = false;
    /*@cc_on
      msie = true;
      @if (@_jscript_version >= 9)
        msie9 = true;
      @end
    @*/

    if (!msie || msie && msie9) {
      hljs.highlightAll()
      hljs.initLineNumbersOnLoad();
    }
})();
</script>

<div class="footer">
    
    <div style="float:right;">generated on 2025-06-15 18:23</div>
</div>
</body>
</html>
